﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Windows.Forms.DataVisualization.Charting;
using System.Text.RegularExpressions;

using NPOI.XWPF.UserModel;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;


namespace TestNPOIPro
{
  public partial class FormMain : Form
  {
    public FormMain()
    {
      InitializeComponent();
    }

    class PicObj
    {
      public string path { get; set; } 
      public string name { get; set; }
      public int width { get; set; }
      public int height { get; set; }
    }

    private void button1_Click(object sender, EventArgs e)
    {
            string Templatepath = "D:\\TestPro\\TestNPOIPro\\Doc\\NPOI测试.docx";

            Dictionary<string, string> dicTexts = new Dictionary<string, string>();
            dicTexts.Add("{SZ101}","Val101");
            dicTexts.Add("{SZ102}", "Val102");
            dicTexts.Add("{SZ103}", "Val103");
            dicTexts.Add("{SZ104}", "Val104");
            dicTexts.Add("{SZ105}", "Val105");
            dicTexts.Add("{SZ2}", "Val2");
            dicTexts.Add("{XM1}", "XM_Val1");
            dicTexts.Add("{XM2}", "XM_Val2");


            Dictionary<string, PicObj> dicPics = new Dictionary<string, PicObj>();
            dicPics.Add("{TP101}", new PicObj{name = "",path ="D:\\TestPro\\TestNPOIPro\\Doc\\PIC1.jpg",width= 400* 10000,height=300 * 10000});
            dicPics.Add("{TP102}", new PicObj{name = "",path ="D:\\TestPro\\TestNPOIPro\\Doc\\PIC2.jpg",width= 400* 10000,height=300 * 10000});
            dicPics.Add("{TP2}", new PicObj{name = "",path ="D:\\TestPro\\TestNPOIPro\\Doc\\PIC3.jpg",width= 100* 10000,height=50 * 10000});

            using (FileStream stream = File.OpenRead(Templatepath))
            {
              XWPFDocument doc = new XWPFDocument(stream);
              

              //{SZ101}/{SZ102}={SZ103}、
              foreach (XWPFParagraph paragraph in doc.Paragraphs)
              {
                // 替换段落中的文本
                string text = paragraph.ParagraphText;
                foreach (string oldText in dicTexts.Keys)
                {
                  if (text.Contains(oldText))
                  {
                    string newText;
                    if (dicTexts.TryGetValue(oldText, out newText))
                    {                      
                      //text = text.Replace(oldText, newText);
                      paragraph.ReplaceText(oldText, newText);
                    }

                  }

                }

                //图片
                foreach (string sKey in dicPics.Keys)
                {
                  if (text.Contains(sKey))
                  {
                    PicObj picObj;
                    if (dicPics.TryGetValue(sKey, out picObj))
                    {
                      foreach (XWPFRun run in paragraph.Runs)
                      {
                        if (run.Text == sKey && File.Exists(picObj.path))
                        {
                          using (FileStream imgstream = new FileStream(picObj.path, FileMode.Open, FileAccess.Read))
                          {
                            run.AddPicture(imgstream, (int)PictureType.JPEG, picObj.name, picObj.width, picObj.height);
                            
                          }
                                                   
                        }

                      }
                      paragraph.ReplaceText(sKey, null);
                    }

                  }

                }

              }

              //表格
              foreach (XWPFTable table in doc.Tables)
              {
                //行
                foreach (XWPFTableRow tableRow in table.Rows)
                {
                  //单元格
                  foreach (XWPFTableCell tableRowCell in tableRow.GetTableCells())
                  {
                    //段落
                    foreach (XWPFParagraph paragraph in tableRowCell.Paragraphs)
                    {
                      // 替换段落中的文本
                      string text = paragraph.ParagraphText;
                      foreach (string oldText in dicTexts.Keys)
                      {
                        if (text.Contains(oldText))
                        {
                          string newText;
                          if (dicTexts.TryGetValue(oldText, out newText))
                          {
                            //text = text.Replace(oldText, newText);
                            paragraph.ReplaceText(oldText, newText);
                          }

                        }

                      }

                      //图片
                      foreach (string sKey in dicPics.Keys)
                      {
                        if (text.Contains(sKey))
                        {
                          PicObj picObj;
                          if (dicPics.TryGetValue(sKey, out picObj))
                          {
                            foreach (XWPFRun run in paragraph.Runs)
                            {
                              if (run.Text == sKey && File.Exists(picObj.path))
                              {
                                using (FileStream imgstream = new FileStream(picObj.path, FileMode.Open, FileAccess.Read))
                                {
                                  run.AddPicture(imgstream, (int)PictureType.JPEG, picObj.name, picObj.width, picObj.height);

                                }

                              }

                            }
                            paragraph.ReplaceText(sKey, null);
                          }

                        }

                      }

                    }


                  }
                }

              }

              



              FileStream file = new FileStream("D:\\TestPro\\TestNPOIPro\\Doc\\NPOI测试_out.docx", FileMode.Create, FileAccess.Write);
              doc.Write(file);
              file.Close();

            }
    }

    private void button2_Click(object sender, EventArgs e)
    {
      String sQT = "{Titles : [{Text : \"标题\",Font:{Name:\"Microsoft Sans Serif\",Size:14,Bold:\"True\"},ForeColor:\"Red\"}],Width : 600,Height : 400,Series : {IsValueShownAsLabel : \"True\",Label: \"#VALX:#PERCENT\",XValueType : \"String\"}}";
      JObject jsQT = JObject.Parse(sQT);


      String sData = "{\"code\":0,\"data\":[{\"BM\":\"1\",\"SZ\":[301829.4711],\"MC\":\"文本\",\"LX\":0},{\"BM\":\"2\",\"SZ\":[{\"SZ\":131377.1947,\"XM\":\"100\",\"MC\":\"江门市直\"},{\"SZ\":9135.45,\"XM\":\"200\",\"MC\":\"蓬江区\"},{\"SZ\":3769.6034,\"XM\":\"300\",\"MC\":\"江海区\"},{\"SZ\":48517.7743,\"XM\":\"400\",\"MC\":\"新会区\"},{\"SZ\":19851.4429,\"XM\":\"500\",\"MC\":\"鹤山市\"},{\"SZ\":39233.9951,\"XM\":\"600\",\"MC\":\"台山市\"},{\"SZ\":30984.8681,\"XM\":\"700\",\"MC\":\"开平市\"},{\"SZ\":18959.1426,\"XM\":\"800\",\"MC\":\"恩平市\"}],\"MC\":\"饼图\",\"LX\":1},{\"BM\":\"3\",\"SZ\":[{\"SZ\":[131377.1947,129610.7031],\"XM\":\"100\",\"MC\":\"江门市直\"},{\"SZ\":[9135.45,9471.43],\"XM\":\"200\",\"MC\":\"蓬江区\"},{\"SZ\":[3769.6034,4041.2211],\"XM\":\"300\",\"MC\":\"江海区\"},{\"SZ\":[48517.7743,49670.0171],\"XM\":\"400\",\"MC\":\"新会区\"},{\"SZ\":[19851.4429,19012.2345],\"XM\":\"500\",\"MC\":\"鹤山市\"},{\"SZ\":[39233.9951,36977.6131],\"XM\":\"600\",\"MC\":\"台山市\"},{\"SZ\":[30984.8681,29067.0085],\"XM\":\"700\",\"MC\":\"开平市\"},{\"SZ\":[18959.1426,18477.9414],\"XM\":\"800\",\"MC\":\"恩平市\"}],\"MC\":\"直方图\",\"LX\":2},{\"BM\":\"4\",\"SZ\":[{\"SZ\":{\"Y\":[131377.1947,129610.7031],\"X\":[2023,2024]},\"XM\":\"100\",\"MC\":\"江门市直\"},{\"SZ\":{\"Y\":[9135.45,9471.43],\"X\":[2023,2024]},\"XM\":\"200\",\"MC\":\"蓬江区\"},{\"SZ\":{\"Y\":[3769.6034,4041.2211],\"X\":[2023,2024]},\"XM\":\"300\",\"MC\":\"江海区\"},{\"SZ\":{\"Y\":[48517.7743,49670.0171],\"X\":[2023,2024]},\"XM\":\"400\",\"MC\":\"新会区\"},{\"SZ\":{\"Y\":[19851.4429,19012.2345],\"X\":[2023,2024]},\"XM\":\"500\",\"MC\":\"鹤山市\"},{\"SZ\":{\"Y\":[39233.9951,36977.6131],\"X\":[2023,2024]},\"XM\":\"600\",\"MC\":\"台山市\"},{\"SZ\":{\"Y\":[30984.8681,29067.0085],\"X\":[2023,2024]},\"XM\":\"700\",\"MC\":\"开平市\"},{\"SZ\":{\"Y\":[18959.1426,18477.9414],\"X\":[2023,2024]},\"XM\":\"800\",\"MC\":\"恩平市\"}],\"MC\":\"曲线图\",\"LX\":3}]} ";
      JObject jsData = JObject.Parse(sData);
      JArray jaData = (JArray)jsData.GetValue("data");
      foreach (JObject jsChart in jaData)
      {
        int iLX = JsonHelper.GetJTokenValue<int>(jsChart.GetValue("LX"),0);
        if (iLX == 1) //Pie
        {
          SetChartQT(chartPie, jsQT);
                
          chartPie.Series[0].Points.Clear();

          JArray jaPieSZ = (JArray)jsChart.GetValue("SZ");
          foreach (JObject jsPieSZ in jaPieSZ)
          {
            chartPie.Series[0].Points.AddXY(JsonHelper.GetJTokenValue<string>(jsPieSZ.GetValue("MC"), "未知"),
              JsonHelper.GetJTokenValue<double>(jsPieSZ.GetValue("SZ"), 0.00));

          }
          
          //chartPie.Titles.Add(JsonHelper.GetJTokenValue<string>(jsChart.GetValue("MC"), "未知"));
          chartPie.Series[0]["PieLabelStyle"] = "Outside";//将文字移到外侧
          chartPie.Series[0]["PieLineColor"] = "Black";//绘制黑色的连线。
          //chartPie.Series[0].Points.DataBindXY(xData, yData);
          //chartPie.Series[0].Points.Add(yData);

        }
        else if (iLX == 2) //Bar
        {
          SetChartQT(chartBar, jsQT);
          chartBar.Series[0].Points.Clear();
          JArray jaSZ = (JArray)jsChart.GetValue("SZ");
          foreach (JObject jsSZ in jaSZ)
          {
            //xData.Add(JsonHelper.GetJTokenValue<string>(jsPieSZ.GetValue("MC"), "未知"));
            //yData.Add(JsonHelper.GetJTokenValue<double>(jsPieSZ.GetValue("SZ"), 0.00));
            JArray jaSZ1 = (JArray)jsSZ.GetValue("SZ");

            chartBar.Series[0].Points.AddXY(JsonHelper.GetJTokenValue<string>(jsSZ.GetValue("MC"), "未知"),JsonHelper.GetJTokenValue<double>(jaSZ1[0], 0.00) );
            chartBar.Series[1].Points.AddXY(JsonHelper.GetJTokenValue<string>(jsSZ.GetValue("MC"), "未知"),JsonHelper.GetJTokenValue<double>(jaSZ1[1], 0.00) );


          }

        }
        else if (iLX == 3) //Line
        {
          SetChartQT(chartLine, jsQT);
          int iXH = 0;
          chartLine.Series[0].Points.Clear();
          JArray jaSZ = (JArray)jsChart.GetValue("SZ");
          foreach (JObject jsSZ in jaSZ)
          {
            //xData.Add(JsonHelper.GetJTokenValue<string>(jsPieSZ.GetValue("MC"), "未知"));
            //yData.Add(JsonHelper.GetJTokenValue<double>(jsPieSZ.GetValue("SZ"), 0.00));
            JObject jaSZ1 = (JObject)jsSZ.GetValue("SZ");

            List<object> jaSZX = ((JArray)jaSZ1.GetValue("X")).ToObject<List<object>>();
            List<double> jaSZY = ((JArray)jaSZ1.GetValue("Y")).ToObject<List<double>>();

            chartLine.Series[iXH].LegendText = JsonHelper.GetJTokenValue<string>(jsSZ.GetValue("MC"), "未知");
            chartLine.Series[iXH].IsValueShownAsLabel = true;
            for (int i = 0; i < jaSZX.Count; i++)
            {
              chartLine.Series[iXH].Points.AddXY(jaSZX[i], jaSZY[i]);
            }
              
        
            iXH++;
          }
          
        }


      }


    }

    public void SetChartQT(Chart chart, JObject jsQT)
    {
      //String sQT = "{Titles : [{Text : \"标题\",Font:{Name:\"Microsoft Sans Serif\",Size:10,Bold:\"False\"},ForeColor:\"Black\"}],Size :{Width : 500,Height : 400},Series : {IsValueShownAsLabel : \"True\",Label: \"#VALX:#PERCENT\",XValueType : \"String\"}}";
      chart.Titles.Clear();
      if (jsQT.Property("Titles") != null)
      {
        JArray jaTitles = (JArray)jsQT.GetValue("Titles");
        foreach (JObject jsTitle in jaTitles)
        {
          if (JsonHelper.GetJTokenValue<string>(jsTitle.GetValue("Text"), "") != "")
          {
            Title title = chart.Titles.Add(JsonHelper.GetJTokenValue<string>(jsTitle.GetValue("Text"), ""));
            //
            if (jsTitle.Property("Font") != null)
            {
              JObject jsFont = (JObject)jsTitle.GetValue("Font");

              FontStyle fs = new FontStyle();
              if (JsonHelper.GetJTokenValue<string>(jsFont.GetValue("Bold"), "False") == "True")
              {
                fs = fs | FontStyle.Bold;
              }

              title.Font = new Font(JsonHelper.GetJTokenValue<string>(jsFont.GetValue("Name"), "Microsoft Sans Serif"), 
                JsonHelper.GetJTokenValue<int>(jsFont.GetValue("Size"), 14), fs);

            }
            title.ForeColor = Color.FromName(JsonHelper.GetJTokenValue<string>(jsTitle.GetValue("ForeColor"), "Black"));
          }

        }  
      }

      if (JsonHelper.GetJTokenValue<int>(jsQT.GetValue("Width"), 0) != 0)
      {
        chart.Width = JsonHelper.GetJTokenValue<int>(jsQT.GetValue("Width"), 0);
      }

      if (JsonHelper.GetJTokenValue<int>(jsQT.GetValue("Height"), 0) != 0)
      {
        chart.Height = JsonHelper.GetJTokenValue<int>(jsQT.GetValue("Height"), 0);
      }

      if (jsQT.Property("Series") != null)
      {
        JObject jsSeries = (JObject)jsQT.GetValue("Series");
        foreach (Series serie in chart.Series)
        {
          serie.IsValueShownAsLabel = JsonHelper.GetJTokenValue<string>(jsSeries.GetValue("IsValueShownAsLabel"), "False") == "True";
          serie.Label = JsonHelper.GetJTokenValue<string>(jsSeries.GetValue("Label"), "");
          serie.XValueType = (ChartValueType)Enum.Parse(typeof(ChartValueType), JsonHelper.GetJTokenValue<string>(jsSeries.GetValue("XValueType"), "Auto"));
 
        }



      }

    }

    private void button3_Click(object sender, EventArgs e)
    {
      string GSPattern = @"(\{Get[Text|Chart][A-Za-z0-9]+\(([A-Za-z0-9,\[\]]*?)\)\})";

       string sText = "{GetTextSZ(DWBM[100],KMBM[10201])}{GetTextSZ(DWBM[101],KMBM[102,101])}";
      MatchCollection matches = Regex.Matches(sText, GSPattern);

       foreach (Match match in matches)
       {
         richTextBox1.AppendText(match.Value+"\n");

       }


    }
  }
}
